script "mergDataGridScroller Behavior"
#I think this is based on v. 1.2, doesn't suffer from the header scroll issue.

local sLabelHeight -- used for handling showName = true

################################### ENGINE MESSAGES

on resizeControl
   handleLayout
   pass resizeControl
end resizeControl

on newGroup -- automatically set a property of all new groups
   if the long id of the target is the long id of me and not the backgroundBehavior of me then
      handleOpen
   end if
   pass newGroup
end newGroup

on preOpenControl
   -- only do this stuff once
   if the short name of the target is the short name of grp 1 of me then
      handleOpen
   end if
   pass preOpenControl
end preOpenControl

on closeControl
   -- only do this stuff once
   if the long id of the target is the long id of me  and not the backgroundBehavior of me then
      handleClose
   end if
   pass closeControl
end closeControl

-- fixes the sLabelHeight if you re-select the control after 
-- setting properties that alter the label
on selectedObjectChanged
   put the height of me - the formattedHeight of me into sLabelHeight
   pass selectedObjectChanged
end selectedObjectChanged

################################### PRIVATE

###### lifecycle

-- reset the control layout
private command handleLayout
   lock screen
   --set the boundingRect of me to the rect of me
   put internalRect() into tRect
   -- layout inner controls here
   set the rect of group 1 of me to tRect
   if the environment = "mobile" then
      if the platform = "iPhone" then
         sizeScrollbars
      else
         updateContentRect
      end if
   end if
end handleLayout

-- a card was displayed with the control on it
private command handleOpen
   put the height of me - the formattedHeight of me into sLabelHeight
   -- datagrid needs to initialise first
   if the short name of the target is the short name of grp 1 of me then
      if the environment = "mobile" then
         set the dgProp["show vscrollbar"]  of group 1 of me to false
         set the dgProp["show hscrollbar"]  of group 1 of me to false
         if the platform = "iPhone" then
            createScroller
         else
            sizeScrollbars
            hide grc "VScroll" of me
            hide grc "HScroll" of me
         end if
      else
         set the dgProp["show vscrollbar"]  of group 1 of me to auto
         set the dgProp["show hscrollbar"]  of group 1 of me to auto
         hide grc "VScroll" of me
         hide grc "HScroll" of me
      end if
   end if
end handleOpen

-- a card was closed with the control on it
private command handleClose
   if the short name of the target is the short name of me then
      if the environment = "mobile" then #and the platform = "iPhone" then
         iPhoneControlDelete sScrollerId
      end if
   end if
end handleClose

###### utility

private function internalRect
   local tMargins
   put the margins of me into tMargins
   -- handle different forms of margins
   if the number of items of tMargins <> 4 then
      put item 1 to 4 of (tMargins,tMargins,tMargins,tMargins) into tMargins
   end if
   -- handle showBorder
   if the showBorder of me then
      repeat with X =1 to 4
         add the borderWidth of me to item X of tMargins
      end repeat
   end if
   -- handle showName -- poor solution
   if the showName of me then
      add sLabelHeight to item 2 of tMargins
   end if
   return insetRect(the rect of me,tMargins)
end internalRect

private function insetRect pRect,pInset
   add item 1 of pInset to item 1 of pRect
   add item 2 of pInset to item 2 of pRect
   subtract item 3 of pInset from item 3 of pRect
   subtract item 4 of pInset from item 4 of pRect
   return pRect
end insetRect


## DropTools Compatible
on DropTools_DragDrop
   init
   set the selectGroupedControls of me to true
end DropTools_DragDrop

on LiveObject_DragDrop
   init
end LiveObject_DragDrop

private command init
   AddDataGrid
   put the relayerGroupedControls into tRelayer
   set the relayerGroupedControls to true
   set the layer of group 1 of me to the layer of me+1
   set the relayerGroupedControls to tRelayer
end init

-------- iPhone stuff
local sScrollerId

on scrollerDidScroll pOffsetX, pOffsetY
   set the dgVScroll of grp 1 of me to pOffsetY
   set the dgHScroll of grp 1 of me to pOffsetX
end scrollerDidScroll

on scrollerBeginDrag
   updateContentRect
end scrollerBeginDrag

private command createScroller
   hide grc "VScroll" of me
   hide grc "HScroll" of me
   iphoneControlCreate "scroller", the short name of me #mikey
   put the result into sScrollerId
   updateContentRect
   iphoneControlSet sScrollerId, "visible", "true"
   iphoneControlSet sScrollerId, "canBounce", "true"
   iphoneControlSet sScrollerId, "pagingEnabled", "false"
   iphoneControlSet sScrollerId, "canScrollToTop", "true"
   iphoneControlSet sScrollerID, "canCancelTouches","true" #mikey
   iphoneControlSet sScrollerID, "delayTouches","true" #mikey
end createScroller

command updateContentRect
   if the environment = "mobile" and the platform = "iPhone" then
      iphoneControlSet sScrollerId, "rect", the rect of grp 1 of me
      put the dgFormattedHeight of grp 1 of me into tHeight
      add 20 to tHeight #v. 1.0.5 debug b/c I THINk the header height is causing the area, and therefore the scroll, to not be correct.
      # this causes the script to crash add dgprops["Header Height"] of group 1 of me to tHeight #mikey because headers are people, too and when they grow, their scrollers must, too.
      put the dgFormattedWidth of grp 1 of me into tWidth
      iphoneControlSet sScrollerId, "contentRect", (0, 0, tWidth,tHeight)
   end if
end updateContentRect

-------- Android stuff

# the event id and initial swipe time and position
local sTouchId,sOldX,sOldY,sTime,sRateX,sRateY

constant kDecelerationFrequency = 5
constant kDecelerationRate = 0.975

on touchStart pID
   put 0 into sRateX
   put 0 into sRateY
   if the environment = "mobile" and the platform = "android" then
      sizeScrollbars
      if the dgFormattedHeight of grp 1 of me/the height of grp 1 of me > 1 then show grc "VScroll" of me
      if the dgFormattedWidth of grp 1 of me/the width of grp 1 of me > 1 then show grc "HScroll" of me
   end if
   pass touchStart
end touchStart

on touchMove pID, pX, pY
   if the environment = "mobile" and the platform = "android" then
      put the milliseconds into tTime
      if pID <> sTouchID then
         put pID into sTouchID
      else
         put (pX-sOldX)/(tTime-sTime)*10 into sRateX
         put (pY-sOldY)/(tTime-sTime)*10 into sRateY
         put pX-sOldX into tMoveX
         put pY-sOldY into tMoveY
         set the dgVScroll of grp 1 of me to max(0,the dgVScroll of grp 1 of me-tMoveY)
         set the dgHScroll of grp 1 of me to max(0,the dgHScroll of grp 1 of me-tMoveX)
         set the loc of grc "VScroll" of me to the right of grp 1 of me -5,the top of grp 1 of me+the height of grc "VScroll" of me div 2+(the dgVScroll of grp 1 of me/the dgFormattedHeight of grp 1 of me)*(the height of grp 1 of me-4)
         set the loc of grc "HScroll" of me to the left of grp 1 of me+the width of grc "HScroll" of me div 2+(the dgHScroll of grp 1 of me/the dgFormattedWidth of grp 1 of me)*(the width of grp 1 of me-4),the bottom of grp 1 of me -5
      end if
      put pX into sOldX
      put pY into sOldY
      put tTime into sTime
   end if
   pass touchMove
end touchMove

on touchEnd pId
   if the environment = "mobile" and the platform = "android" then
      if pId = sTouchId then
         decelerateScroll pId
      end if
   end if
   pass touchEnd
end touchEnd

command decelerateScroll pID
   if pID = sTouchId then
      put sRateX*kDecelerationRate into sRateX
      put sRateY*kDecelerationRate into sRateY
      if (sRateX+sRateY) > 1 or (sRateX+sRateY) < -1 then 
         set the dgVScroll of grp 1 of me to max(0,the dgVScroll of grp 1 of me-trunc(sRateY))
         set the dgHScroll of grp 1 of me to max(0,the dgHScroll of grp 1 of me-trunc(sRateX))
         set the loc of grc "VScroll" of me to the right of grp 1 of me -5,the top of grp 1 of me+the height of grc "VScroll" of me div 2+(the dgVScroll of grp 1 of me/the dgFormattedHeight of grp 1 of me)*(the height of grp 1 of me-4)
         set the loc of grc "HScroll" of me to the left of grp 1 of me+the width of grc "HScroll" of me div 2+(the dgHScroll of grp 1 of me/the dgFormattedWidth of grp 1 of me)*(the width of grp 1 of me-4),the bottom of grp 1 of me -5
         send decelerateScroll&&pID to me in kDecelerationFrequency milliseconds
      else
         hide grc "VScroll" of me
         hide grc "HScroll" of me
      end if
   end if
end decelerateScroll


command sizeScrollbars
   put the dgFormattedHeight of grp 1 of me/the height of grp 1 of me into tRatio
   if tRatio > 1 then 
      set the height of grc "VScroll" of me to the height of grp 1 of me/tRatio
   end if
   put the dgFormattedWidth of grp 1 of me/the width of grp 1 of me into tRatio
   if tRatio > 1 then 
      set the width of grc "HScroll" of me to the width of grp 1 of me/tRatio
   end if
end sizeScrollbars


-------------------
--------Data grid stuff

constant kResourceStack = "revDataGridLibrary"
constant kTemplateStack = "Data Grid Templates"

command AddDataGrid
   put internalRect() into tRect
   put the topLeft of me into tTopLeft
   if there is a group 1 of me then delete group 1 of me
   
   put the short name this stack into tStack
   put the long id of group "DataGrid" of group "Templates" of stack kResourceStack into tDataGridControl 
   
   local theError
   ConfirmPresenceOfTemplateStack tStack
   put the result into theError
   
   if theError is empty then
      local theDataGridGroup
      copy tDataGridControl to the long id of me
      put it into theDataGridGroup
      set the rect of theDataGridGroup to tRect
      
      CreateTemplateForControl tStack
      put the result into tTemplateGroupSource
      
      set the visible of theDataGridGroup to true
      
      set the dgProps["record template"] of theDataGridGroup to tTemplateGroupSource
      send "ResetControl" to theDataGridGroup
      set the topLeft of me to tTopLeft
   end if
   return theError
end AddDataGrid

## Assumes resource stack already exists
command ConfirmPresenceOfTemplateStack pStack
   -----
   local theLineNo
   local theSubstack, tStackName
   local tUnique
   -----
   
   local theMainStack
   put the mainstack of stack pStack into theMainStack
   
   local i
   repeat for each line theSubstack in the substacks of stack theMainStack
      add 1 to i
      if theSubstack begins with kTemplateStack then
         put i into theLineNo
         exit repeat
      end if
   end repeat
   
   -- put the executioncontexts
   -- answer pStack & cr & theLineNo
   
   local msgsAreLocked
   put the lockmessages into msgsAreLocked
   lock messages
   
   if theLineNo < 1 then
      lock screen
      
      put the milliseconds into tUnique
      put kTemplateStack && tUnique into tStackName
      set the topleft of the templatestack to -1000,-1000
      create stack tStackName
      close stack tStackName 
      set the mainstack of stack tStackName to the mainstack of stack pStack
      
      set the width of stack tStackName to 600
      set the height of stack tStackName to 400
      set the topleft of stack tStackName to 180,180
      
      unlock screen
      
   else
      put line theLineNo of the substacks of stack theMainStack into tStackName
   end if
   
   local theRestoreStack
   put the defaultstack into theRestoreStack
   set the defaultstack to tStackName
   
   ## Make sure we have an instructions background
   if there is not a background "_DataGridTemplateInstructions_" of stack tStackName then
      copy group "_DataGridTemplateInstructions_" of stack kResourceStack to card 1 of stack tStackName
      -- MW-2011-03-16: Make sure the instructions is actually a background.
      set the backgroundBehavior of group "_DataGridTemplateInstructions_" of card 1 of stack tStackName to true
   end if
   
   ## Make sure it appears on every card
   repeat with i = 1 to the number of cards of stack tStackName
      if there is not a group "_DataGridTemplateInstructions_" of card i of stack tStackName then
         place background "_DataGridTemplateInstructions_" onto card i
         set the bottomleft of group "_DataGridTemplateInstructions_" of card i to 0, the height of card i
      end if
   end repeat
   
   set the defaultstack to theRestoreStack
   
   set the lockmessages to msgsAreLocked
   
   return empty
end ConfirmPresenceOfTemplateStack


## Assumes presence of template stack in memory
command CreateTemplateForControl pStack
   -----
   local theLineNo
   local theSubstack, tStackName
   local theTemplateGroup
   local tRestore
   -----
   put the defaultstack into tRestore
   lock screen
   
   local msgsAreLocked
   put the lockmessages into msgsAreLocked
   lock messages
   
   local theMainStack
   put the mainstack of stack pStack into theMainStack
   
   local i
   repeat for each line theSubstack in the substacks of stack theMainStack
      add 1 to i
      if theSubstack begins with kTemplateStack then
         put i into theLineNo
         exit repeat
      end if
   end repeat
   put line theLineNo of (the substacks of stack theMainStack) into tStackName
   
   set the topleft of stack tStackname to -1000,-1000
   hide stack tStackName
   toplevel stack tStackName
   set the defaultstack to tStackName
   if the number of controls on this card > 0 then 
      create card
   end if
   
   copy group "Default Row Template" of group "Templates" of stack kResourceStack to the current card of the defaultstack
   put it into theTemplateGroup
   set the name of theTemplateGroup to "Row Template"
   set the topleft of theTemplateGroup to 0,0
   
   create button "Behavior Script"
   set the visible of it to false
   
   set the script of it to the uDefaultScript of button "Default Script" of stack kResourceStack
   
   set the parentscript of theTemplateGroup to it
   
   ## Provide instructions
   set the bottomleft of group "_DataGridTemplateInstructions_" to the bottomleft of the current card of the defaultstack
   
   close stack tStackName
   show stack tStackName
   set the topleft of stack tStackName to 180,180
   
   set the defaultstack to tRestore
   
   set the lockmessages to msgsAreLocked
   unlock screen
   
   return theTemplateGroup
end CreateTemplateForControl



#<mikey 05.08.15>
on scrollToTop
   #scrolls both the scroller and the datagrid
   iphonecontrolset sScrollerID,"vScroll",0
   set the dgvScroll of group "dataGrid" of me to 0
end scrollToTop
#</mikey 05.08.15>
